#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import re

from version import Version, MinVersion, MaxVersion

class VersionRangeException(Exception):
    def __init__(self, message):
        self.__message = message

    def __str__(self):
        return self.__message

class VersionRange:
    def __init__(self, range):
        self.__comparer_more, self.__min_version, self.__comparer_less, self.__max_version = self.__process_range(range)

        if (self.__min_version > self.__max_version):
            raise VersionRangeException('Bad range was specified: ' + range)

    @property
    def min_version(self):
        return self.__min_version

    @property
    def max_version(self):
        return self.__max_version

    def contains(self, version):
        return self.__comparer_more(version, self.__min_version) and self.__comparer_less(version, self.__max_version)

    def __process_range(self, range):
        result = []

        if re.search("[\[\(] *,? *[\]\)]", range):
            return [self.__equal, Version.Any(), self.__equal, Version.Any()] 

        ranges = range.split(",")
        min_value = ranges[0].strip()
        max_value = ranges[-1].strip()
        index_min = 0
        index_max = len(max_value)

        if ((cmp(min_value, "(") == 0) or (cmp(min_value, "[") == 0)):
            result.append(self.__more)
            result.append(MinVersion(""))
        else:
            if min_value[0] == "(":
                index_min = 1
                result.append(self.__more)
            elif min_value[0] == "[":
                index_min = 1
                result.append(self.__more_equal)
            else:
                result.append(self.__equal)
            result.append(Version(min_value[index_min:]))

        if ((cmp(max_value, ")") == 0) or (cmp(max_value, "]") == 0)):
            result.append(self.__less)
            result.append(MaxVersion(""))
        else:
            if max_value[-1] == ")":
                index_max = -1
                result.append(self.__less)
            elif max_value[-1] == "]":
                index_max = -1
                result.append(self.__less_equal)
            else:
                result.append(self.__equal)
            result.append(Version(max_value[:index_max]))

        return result

    def __equal(self, version1, version2):
            return cmp(version1, version2) == 0

    def __less_equal(self, version1,version2):
            return cmp(version1, version2) <= 0

    def __less(self, version1,version2):
            return cmp(version1, version2) < 0

    def __more_equal(self, version1,version2):
            return cmp(version1, version2) >= 0

    def __more(self, version1,version2):
            return cmp(version1, version2) > 0

class NamedVersionRange(VersionRange):

    def __init__(self, name, range):
        self.name = name
        VersionRange.__init(self, range)